/**
 * @file	userHandler.c
 * @brief	User Control Example
 * @version 1.0
 * @date	2014/07/15
 * @par Revision
 *			2014/07/15 - 1.0 Release
 * @author	
 * \n\n @par Copyright (C) 1998 - 2014 WIZnet. All rights reserved.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "userHandler.h"
#include "types.h"
#include "common.h"
#include "ConfigData.h"
#include "httpParser.h"
#include "I2C.h"

extern uint8_t netPort[2];
extern wiz_NetInfo netAddr;
//IOStorage IOdata;

// Pre-defined Get CGI functions
void make_json_devinfo(uint8_t * buf, uint16_t * len);
void make_json_netinfo(uint8_t * buf, uint16_t * len);
void make_json_uartinfo(uint8_t * buf, uint16_t * len, uint8_t uart_sel);
void make_json_dio(uint8_t * buf, uint16_t * len, uint8_t pin);
void make_json_ain(uint8_t * buf, uint16_t * len, uint8_t pin);

// Pre-defined Set CGI functions
uint8_t set_devinfo(uint8_t * uri);
uint8_t set_netinfo(uint8_t * uri);
uint8_t set_uartinfo(uint8_t * uri, uint8_t uart_sel);

uint8_t * set_basic_config_setting(uint8_t * uri)
{
	uint8_t * param;
	uint8_t str_size;
	S2E_Packet *value = get_S2E_Packet_pointer();

	// Redirection IP address init
	uint8_t return_ip[4] = {value->network_info_common.local_ip[0],
							value->network_info_common.local_ip[1],
							value->network_info_common.local_ip[2],
							value->network_info_common.local_ip[3]};

	uint8_t * ip = return_ip;

	if((param = get_http_param_value((char *)uri, "devicename")))
	{
		memset(value->module_name, 0x00, 25);
		if((str_size = strlen((char*)param)) > 24) str_size = 24; // exception handling
		memcpy(value->module_name, param, str_size);
	}

	if((param = get_http_param_value((char *)uri, "dhcp")))
	{
		if(strstr((char const*)param, "1") != NULL) value->options.dhcp_use = 1; // DHCP mode
		else value->options.dhcp_use = 0; // Static mode
	}

	if(value->options.dhcp_use == 0) // Static mode
	{
		if((param = get_http_param_value((char *)uri, "lip")))
		{
			inet_addr_((u_char*)param, value->network_info_common.local_ip);

			return_ip[0] = value->network_info_common.local_ip[0];
			return_ip[1] = value->network_info_common.local_ip[1];
			return_ip[2] = value->network_info_common.local_ip[2];
			return_ip[3] = value->network_info_common.local_ip[3];
		}
		if((param = get_http_param_value((char *)uri, "gw")))
		{
			inet_addr_((u_char*)param, value->network_info_common.gateway);
		}
		if((param = get_http_param_value((char *)uri, "sub")))
		{
			inet_addr_((u_char*)param, value->network_info_common.subnet);
		}
		if((param = get_http_param_value((char *)uri, "dns")))
		{
			inet_addr_((u_char*)param, value->options.dns_server_ip);
		}
	}
	save_S2E_Packet_to_storage();

	return ip;
}
void make_cgi_basic_config_response_page(uint16_t delay, uint8_t * url, uint8_t * cgi_response_buf, uint16_t * len)
{
	S2E_Packet *value = get_S2E_Packet_pointer();

	if(value->options.dhcp_use == 1) // Static -> DHCP, DHCP -> DHCP
	{
		*len = sprintf((char *)cgi_response_buf,"<html><head><title>WIZ550web - Configuration</title><body>Reboot Complete. Please try to connect to the IP address assigned by the <span style='color:red;'>DHCP server</span></body></html>");
	}
	else // Static -> Static, DHCP -> Static
	{
		*len = sprintf((char *)cgi_response_buf,"<html><head><title>WIZ550web - \
									 Configuration</title><script language=javascript>j=%d;\
										function func(){document.getElementById('delay').innerText=\
											' '+j+' ';if(j>0)j--;setTimeout('func()',1000);if(j<=0)\
												location.href='http://%d.%d.%d.%d';}</script></head>\
													<body onload='func()'>Please wait for a while, \
													the module will boot in<span style='color:red;' \
														id='delay'></span> seconds.</body></html>", 
															delay, url[0], url[1], url[2], url[3]);
	}
	return;
}

void make_json_devinfo(uint8_t * buf, uint16_t * len)
{
	S2E_Packet *value = get_S2E_Packet_pointer();

	*len = sprintf((char *)buf, "DevinfoCallback({\"fwver\":\"%d.%d.%d\",\
											\"devname\":\"%s\",\
											\"pcode\":\"%d-%d-%d\",\
											\"mac\":\"%02X:%02X:%02X:%02X:%02X:%02X\"\
											});",
											value->fw_ver[0], value->fw_ver[1], value->fw_ver[2],
											value->module_name,
											value->module_type[0],value->module_type[1],value->module_type[2],
											value->network_info_common.mac[0],value->network_info_common.mac[1],value->network_info_common.mac[2],value->network_info_common.mac[3],value->network_info_common.mac[4],value->network_info_common.mac[5]
											);
}

void make_json_netinfo(uint8_t * buf, uint16_t * len)
{
	S2E_Packet *value = get_S2E_Packet_pointer();

	*len = sprintf((char *)buf, "NetinfoCallback({\"ip\":\"%d.%d.%d.%d\",\
											\"gw\":\"%d.%d.%d.%d\",\
											\"sub\":\"%d.%d.%d.%d\",\
											\"port\":\"%d\",\
											});",
											value->network_info_common.local_ip[0],value->network_info_common.local_ip[1],value->network_info_common.local_ip[2],value->network_info_common.local_ip[3],
											value->network_info_common.gateway[0],value->network_info_common.gateway[1],value->network_info_common.gateway[2],value->network_info_common.gateway[3],
											value->network_info_common.subnet[0],value->network_info_common.subnet[1],value->network_info_common.subnet[2],value->network_info_common.subnet[3],
											value->network_info_common.ctrlport
											);
}

// Parameters: URI, Buffer, Length
uint8_t predefined_get_cgi_processor(uint8_t * uri_name, uint8_t * buf, uint16_t * len)
{
	uint8_t ret = 1;	// ret = 1 means 'uri_name' matched
	if(strcmp((const char *)uri_name, "get_devinfo.cgi") == 0)
	{
		make_json_devinfo(buf, len);
	}
	else if(strcmp((const char *)uri_name, "get_netinfo.cgi") == 0)
	{
		make_json_netinfo(buf, len);
	}
	return ret;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Predefined Set CGI functions
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t set_devinfo(uint8_t * uri)
{
	uint8_t ret = 0;
	uint8_t * param;
	uint8_t str_size;
	S2E_Packet *value = get_S2E_Packet_pointer();

	if((param = get_http_param_value((char *)uri, "devname")))
	{
		memset(value->module_name, 0x00, 16);
		if((str_size = strlen((char*)param)) > 15) str_size = 15; // exception handling
		memcpy(value->module_name, param, str_size);

		ret = 1;
	}
	if(ret == 1)
		WriteBytes(E2ROMaddr,DEVNAMEADDR,value->module_name,str_size+1);
//		save_S2E_Packet_to_storage();
	return ret;
}

uint8_t set_netinfo(uint8_t * uri)
{
	uint8_t ret = 0;
	uint8_t * param;

	S2E_Packet *value = get_S2E_Packet_pointer();


	if((param = get_http_param_value((char *)uri, "dhcp")))
	{
		if(strstr((char const*)param, "1") != NULL) value->options.dhcp_use = 1; // DHCP mode
		else value->options.dhcp_use = 0; // Static mode
		ret = 1;
	}

	if(value->options.dhcp_use == 0) // Static mode
	{
		if((param = get_http_param_value((char *)uri, "ip")))
		{
			inet_addr_((u_char*)param, value->network_info_common.local_ip);
			WriteBytes(E2ROMaddr,DeviceIPAddr,value->network_info_common.local_ip,4);
			ret = 1;
		}
		if((param = get_http_param_value((char *)uri, "gw")))
		{
			inet_addr_((u_char*)param, value->network_info_common.gateway);
			WriteBytes(E2ROMaddr,GatewayAddr,value->network_info_common.gateway,4);
			ret = 1;
		}
		if((param = get_http_param_value((char *)uri, "sub")))
		{
			inet_addr_((u_char*)param, value->network_info_common.subnet);
			WriteBytes(E2ROMaddr,NetMaskAddr,value->network_info_common.subnet,4);
			ret = 1;
		}
		if((param = get_http_param_value((char *)uri, "port")))
		{
			value->network_info_common.ctrlport = atoi((char const *)param);
			netPort[0] = value->network_info_common.ctrlport>>8;
			netPort[1] = value->network_info_common.ctrlport&0xFF;
			WriteBytes(E2ROMaddr,NetPortAddr,netPort,2);
			ret = 1;
		}
	}
	
	if(ret == 1) 
		get_S2E_Packet(&netAddr);
//		save_S2E_Packet_to_storage();
	return ret;
}

// Parameters: URI, Parameters, Buffer, Length
uint8_t predefined_set_cgi_processor(uint8_t * uri_name, uint8_t * uri, uint8_t * buf, uint16_t * len)
{
	uint8_t ret = 1;	// ret = 1 means 'uri_name' matched
	uint8_t val = 0;

	// Devinfo; devname
	if(strcmp((const char *)uri_name, "set_devinfo.cgi") == 0)
	{
		val = set_devinfo(uri);
		*len = sprintf((char *)buf, "%d", val);
	}
	// Netinfo; ip, gw, sub, dns, dhcp
	else if(strcmp((const char *)uri_name, "set_netinfo.cgi") == 0)
	{
		val = set_netinfo(uri);
		*len = sprintf((char *)buf, "%d", val);
	}
	else
	{
		ret = 0;
	}


	return ret;
}

// return value - 	0: Failed (no custom command)
//					1: Success
//					2: Failed (custom command ok, but process error - e.g., I/O control failed)
uint8_t custom_command_handler(
	uint8_t * buf				/**< custom command: pointer to be parsed */
	)
{
	uint8_t ret = NO_CUSTOM_COMMAND;

#ifdef _CUSTOM_COMMAND_DEBUG_
			//printf("[CWD] ");
#endif

	// if the command process succeed, ret = COMMAND_SUCCESS;
	// if the command received but process failed, ret = COMMAND_ERROR;
	// if the http request is not custom command, ret = NO_CUSTOM_COMMAND;

	return ret;
}
